<?php

namespace App\Services\Postman;

use App\Exceptions\Response\ServiceException;
use App\Models\Game\Platform\Org\AccessKey;
use Illuminate\Support\Facades\Http;

class ApiService
{

    /**
     * 玩家登录
     *
     * @var string
     */
    const URI_LOGIN = '/v2/player/login';

    /**
     * 订单转入
     *
     * @var string
     */
    const URI_TRANSFER_IN = '/v2/order/transfer_in';

    /**
     * 订单转出
     *
     * @var string
     */
    const URI_TRANSFER_OUT = '/v2/order/transfer_out';

    /**
     * 订单信息
     *
     * @var string
     */
    const URI_ORDER_INFO = '/v2/order/info';

    /**
     * 制作链接地址
     *
     * @param string $uri
     * @return string
     */
    protected static function makeUri(string $uri): string
    {
        return rtrim(config('app.domain.api'), '/') . $uri;
    }

    /**
     * 制作签名参数
     *
     * @param int $platCode
     * @return array
     */
    protected static function makeSignParam($platCode)
    {
        // 获取秘钥
        if (is_null($accessKey = AccessKey::where('plat_code', $platCode)->first())) {
            throw new ServiceException(ServiceException::SERVICE_NOT_EXIST_ACCESS_KEY);
        }
        // 当前时间
        $time = time();
        // 签名参数
        return [
            'AccessKeyId' => $accessKey->access_key_id,
            'Timestamp' => $time, 'Nonce' => (string)$time,
            'Sign' => $accessKey->makeSignature($time, $time),
        ];
    }

    /**
     * POST 公共请求
     *
     * @param string $uri
     * @param array $data
     * @return mixed|null
     * @throws ServiceException
     */
    public static function post(string $uri, array $data = [])
    {
        // 制作签名参数
        $data = array_merge($data, self::makeSignParam($data['plat_code']));

        // 发起HTTP请求
        try {
            $response = Http::timeout(20)->post(self::makeUri($uri), $data);
        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            throw new ServiceException(ServiceException::SERVICE_API_SERVICE_REQUEST_TIMEOUT);
        }
        // HTTP错误
        if (!$response->successful()) {
            throw new ServiceException(ServiceException::SERVICE_API_SERVICE);
        }
        // 返回数据
        $result = $response->json();

        // Api服务错误
        if ($result['resp_msg']['code'] != 200) {
            throw new ServiceException(ServiceException::SERVICE_API_SERVICE, $result['resp_msg']['message']);
        }

        return $result['resp_data'] ?? null;
    }
}
